﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Gmantis.Controls.DataGrid
{
    public enum DataGridGridLinesVisibility
    {
        None,
        Horizontal,
        Vertical,
        All
    }

    [TemplatePart(Name = "BottomLine", Type = typeof(Rectangle)), 
    TemplatePart(Name = "LeftLine", Type = typeof(Rectangle)), 
    TemplatePart(Name = "TopLine", Type = typeof(Rectangle)), 
    TemplatePart(Name = "RightLine", Type = typeof(Rectangle)), 
    StyleTypedProperty(Property = "FocusStyle", StyleTargetType = typeof(DataGridFocusPresenter)), 
    TemplateVisualState(Name = "Unselected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Current", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Selected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "CurrentSelected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Editing", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Valid", GroupName = "ValidationStates"), 
    TemplateVisualState(Name = "InvalidFocused", GroupName = "ValidationStates"), 
    TemplateVisualState(Name = "InvalidUnfocused", GroupName = "ValidationStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
    public class DataGridCellPresenter : ContentControl, IRecyclable, INotifyPropertyChanged
    {
        // Fields
        private double _actualHeight;
        internal Rectangle _elementBottomLine;
        internal Rectangle _elementLeftLine;
        internal Rectangle _elementRightLine;
        internal Rectangle _elementTopLine;
        internal bool _isLoaded;
        private bool _isSelected;
        private Point? _mousePosition;
        private Dock _resizeEdge;
        private bool _throwIsMouseOverChanged;
        private ViewColumn _viewColumn;
        private ViewRow _viewRow;
        internal static readonly DependencyProperty BorderThicknessNewProperty;
        public static readonly DependencyProperty BottomLineBrushProperty;
        internal const string BottomLineElementName = "BottomLine";
        internal FrameworkElement CellContent;
        public static readonly DependencyProperty CornerRadiusProperty;
        public static readonly DependencyProperty FocusStyleProperty;
        internal static readonly DependencyProperty ForceMouseOverProperty;
        private const double HalfEdge = 2.0;
        internal bool HaveContent;
        public static readonly DependencyProperty IsCurrentProperty;
        public static readonly DependencyProperty IsEditingProperty;
        public static readonly DependencyProperty IsMouseOverProperty;
        public static readonly DependencyProperty IsSelectedProperty;
        public static readonly DependencyProperty LeftLineBrushProperty;
        internal const string LeftLineElementName = "LeftLine";
        internal DataGridCellsRange MergedRangeCandidate;
        public static readonly DependencyProperty MergedRangeProperty;
        public static readonly DependencyProperty MouseOverBrushProperty;
        public static readonly DependencyProperty PressedBrushProperty;
        internal FrameworkElement ReadOnlyContent;
        public static readonly DependencyProperty RightLineBrushProperty;
        internal const string RightLineElementName = "RightLine";
        public static readonly DependencyProperty SelectedBackgroundProperty;
        public static readonly DependencyProperty TopLineBrushProperty;
        internal const string TopLineElementName = "TopLine";
        public static readonly DependencyProperty ValidationBackgroundProperty;
        public static readonly DependencyProperty ValidationStateProperty;

        // Events
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;
        public event MouseButtonEventHandler MouseLeftButtonDown;
        public event MouseButtonEventHandler MouseLeftButtonUp;
        public event PropertyChangedEventHandler PropertyChanged;

        // Methods
        static DataGridCellPresenter()
        {
            BorderThicknessNewProperty = DependencyProperty.Register("BorderThicknessNew", typeof(Thickness), typeof(DataGridCellPresenter), new PropertyMetadata((d, e) => (d as DataGridCellPresenter).UpdateLines()));
            MergedRangeProperty = DependencyProperty.Register("MergedRange", typeof(DataGridCellsRange), typeof(DataGridCellPresenter), null);
            FocusStyleProperty = DependencyProperty.Register("FocusStyle", typeof(Style), typeof(DataGridCellPresenter), null);
            CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(DataGridCellPresenter), null);
            IsCurrentProperty = DependencyProperty.Register("IsCurrent", typeof(bool), typeof(DataGridCellPresenter), new PropertyMetadata(false, new PropertyChangedCallback(DataGridCellPresenter.OnIsCurrentPropertyChanged)));
            IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnIsSelectedPropertyChanged)));
            IsEditingProperty = DependencyProperty.Register("IsEditing", typeof(bool), typeof(DataGridCellPresenter), new PropertyMetadata(false, new PropertyChangedCallback(DataGridCellPresenter.OnIsEditingPropertyChanged)));
            ValidationStateProperty = DependencyProperty.Register("ValidationState", typeof(ValidationState), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnValidationStatePropertyChanged)));
            LeftLineBrushProperty = DependencyProperty.Register("LeftLineBrush", typeof(Brush), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnLeftLineBrushPropertyChanged)));
            TopLineBrushProperty = DependencyProperty.Register("TopLineBrush", typeof(Brush), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnTopLineBrushPropertyChanged)));
            RightLineBrushProperty = DependencyProperty.Register("RightLineBrush", typeof(Brush), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnRightLineBrushPropertyChanged)));
            BottomLineBrushProperty = DependencyProperty.Register("BottomLineBrush", typeof(Brush), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnBottomLineBrushPropertyChanged)));
            ValidationBackgroundProperty = DependencyProperty.Register("ValidationBackground", typeof(Brush), typeof(DataGridCellPresenter), null);
            IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnIsMouseOverPropertyChanged)));
            ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(DataGridCellPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridCellPresenter.OnForceMouseOverPropertyChanged)));
            MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(DataGridCellPresenter), null);
            PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(DataGridCellPresenter), null);
            SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(DataGridCellPresenter), null);
        }

        public DataGridCellPresenter()
        {
            RoutedEventHandler handler = null;
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(DataGridCellPresenter);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateSelection(false);
                    this.ChangeVisualStateValidation(false);
                    this.ChangeVisualStateCommon(false);
                };
            }
            base.Loaded += handler;
            this.SetCustomDefaultValues();
        }

        void IRecyclable.Collect()
        {
            this.IsCollected = true;
            this.ViewRow.FinalizeCellPresenter(this.ViewColumn);
        }

        object IRecyclable.GetRecyclingKey()
        {
            return this.ViewRow.GetCellPresenterRecyclingKey(this.ViewColumn.Column);
        }

        void IRecyclable.Reuse()
        {
            this.IsCollected = false;
        }

        private bool CanUserResizeRow()
        {
            return ((this.DataGrid == null) || ((this.DataGrid.CanUserResizeRows && this.Row.CanUserResize) && this.Column.CanUserResizeRows));
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateSelection(bool useTransitions)
        {
            if (this.IsCurrent && this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "CurrentSelected", useTransitions);
            }
            if (this.IsEditing)
            {
                VisualStateHelper.GoToState(this, "Editing", useTransitions);
            }
            if (!this.IsCurrent && this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "Selected", useTransitions);
            }
            if ((!this.IsCurrent && !this.IsEditing) && !this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "Unselected", useTransitions);
            }
            if ((this.IsCurrent && !this.IsEditing) && !this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "Current", useTransitions);
            }
        }

        protected void ChangeVisualStateValidation(bool useTransitions)
        {
            if (this.ValidationState == ValidationState.InvalidUnfocused)
            {
                VisualStateHelper.GoToState(this, "InvalidUnfocused", useTransitions);
            }
            if (this.ValidationState == ValidationState.InvalidFocused)
            {
                VisualStateHelper.GoToState(this, "InvalidFocused", useTransitions);
            }
            if (this.ValidationState == ValidationState.Valid)
            {
                VisualStateHelper.GoToState(this, "Valid", useTransitions);
            }
        }

        private Dock? Edge()
        {
            if (this.CanUserResizeRow())
            {
                if (!this._mousePosition.HasValue)
                {
                    return null;
                }
                if ((base.ActualHeight - this._mousePosition.Value.Y) <= 2.0)
                {
                    return (Dock)3;
                }
                if (this._mousePosition.Value.Y < 2.0)
                {
                    return (Dock)2;
                }
            }
            return null;
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private FrameworkElement GoToEditingState()
        {
            RoutedEventHandler handler = null;
            DataGridRow row = this.ViewRow.Row;
            DataGridColumn column = this.ViewColumn.Column;
            FrameworkElement cellElement = row.GetCellEditingContent(column);
            if ((cellElement != null) && (this.ViewRow != null))
            {
                cellElement.DataContext = row.DataItem;
                if (handler == null)
                {
                    handler = delegate(object s, RoutedEventArgs e)
                    {
                        Control firstFocusableControl = cellElement.GetFirstFocusableControl();
                        if (firstFocusableControl != null)
                        {
                            firstFocusableControl.Focus();
                        }
                    };
                }
                cellElement.Loaded += handler;
                this.View.Model.EditingCellUneditedValue = column.PrepareCellForEdit(cellElement);
                this.View.Model.EditingCellContent = cellElement;
                this.ReadOnlyContent = base.Content as FrameworkElement;
                row.UnbindCellContent(this.ReadOnlyContent, column);
                base.Content = cellElement;
                this.View.Model.BeganCellEdit(cellElement);
            }
            return cellElement;
        }

        private void GoToReadOnlyState()
        {
            DataGridColumn column = this.ViewColumn.Column;
            DataGridRow row = this.ViewRow.Row;
            if ((this.ReadOnlyContent != null) && (this.ReadOnlyContent != this.CellContent))
            {
                if (base.Content is FrameworkElement)
                {
                    FrameworkElement content = base.Content as FrameworkElement;
                    FrameworkElement elem = this.GetLogicalFocusedElement();
                    content.DataContext = null;
                    if ((elem == content) || elem.GetAllParents().Contains(content))
                    {
                        this.DataGrid.Focus();
                    }
                }
                row.BindCellContent(this.ReadOnlyContent, column);
                base.Content = this.ReadOnlyContent;
            }
        }

        protected internal virtual void Load()
        {
            this.UpdateSelection();
            this.UpdateValidationState();
            this.UpdateCurrentCell();
            this.UpdateEditingCell();
            this.UpdateLines();
        }

        private void OnAfterApplyTemplate()
        {
            this.UpdateLines();
        }

        public override void OnApplyTemplate()
        {
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementLeftLine = this.GetTemplateChild<Rectangle>("LeftLine", false, ref errors);
            this._elementTopLine = this.GetTemplateChild<Rectangle>("TopLine", false, ref errors);
            this._elementRightLine = this.GetTemplateChild<Rectangle>("RightLine", false, ref errors);
            this._elementBottomLine = this.GetTemplateChild<Rectangle>("BottomLine", false, ref errors);
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to DataGridCellPresenter.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStateSelection(false);
                this.ChangeVisualStateValidation(false);
                this.ChangeVisualStateCommon(false);
                this.OnAfterApplyTemplate();
            }
        }

        private void OnBottomLineBrushChanged(Brush oldValue)
        {
            this.UpdateLines();
        }

        private static void OnBottomLineBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridCellPresenter presenter = d as DataGridCellPresenter;
            Brush oldValue = (Brush)e.OldValue;
            presenter.OnBottomLineBrushChanged(oldValue);
        }

        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);
            if (newContent != null)
            {
                this.CellContent = (FrameworkElement)newContent;
                this.HaveContent = true;
            }
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridCellPresenter).ChangeVisualStateCommon(true);
        }

        private static void OnIsCurrentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridCellPresenter).ChangeVisualStateSelection(true);
        }

        private static void OnIsEditingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridCellPresenter).ChangeVisualStateSelection(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridCellPresenter sender = d as DataGridCellPresenter;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private void OnIsSelectedChanged(bool oldValue)
        {
            this._isSelected = this.IsSelected;
        }

        private static void OnIsSelectedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridCellPresenter presenter = d as DataGridCellPresenter;
            bool oldValue = (bool)e.OldValue;
            presenter.OnIsSelectedChanged(oldValue);
            presenter.ChangeVisualStateSelection(true);
        }

        private void OnLeftLineBrushChanged(Brush oldValue)
        {
            this.UpdateLines();
        }

        private static void OnLeftLineBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridCellPresenter presenter = d as DataGridCellPresenter;
            Brush oldValue = (Brush)e.OldValue;
            presenter.OnLeftLineBrushChanged(oldValue);
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            if (this.View != null)
            {
                this.View.SetMouseOverCell(this.Row, this.Column);
            }
            this._mousePosition = new Point?(e.GetPosition(this));
            this.UpdateCursor();
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            if (this.View != null)
            {
                this.View.ClearMouseOver();
            }
            this._mousePosition = null;
            this.UpdateCursor();
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (this.MouseLeftButtonDown != null)
            {
                this.MouseLeftButtonDown(this, e);
            }
            if (!e.Handled)
            {
                base.OnMouseLeftButtonDown(e);
            }
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            if (this.MouseLeftButtonUp != null)
            {
                this.MouseLeftButtonUp(this, e);
            }
            if (!e.Handled)
            {
                base.OnMouseLeftButtonUp(e);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            this._mousePosition = new Point?(e.GetPosition(this));
            this.UpdateCursor();
        }

        private void OnRightLineBrushChanged(Brush oldValue)
        {
            this.UpdateLines();
        }

        private static void OnRightLineBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridCellPresenter presenter = d as DataGridCellPresenter;
            Brush oldValue = (Brush)e.OldValue;
            presenter.OnRightLineBrushChanged(oldValue);
        }

        private void OnTopLineBrushChanged(Brush oldValue)
        {
            this.UpdateLines();
        }

        private static void OnTopLineBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridCellPresenter presenter = d as DataGridCellPresenter;
            Brush oldValue = (Brush)e.OldValue;
            presenter.OnTopLineBrushChanged(oldValue);
        }

        private static void OnValidationStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridCellPresenter).ChangeVisualStateValidation(true);
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void ResizeMouseDoubleTapped(object sender, TappedEventArgs e)
        {
            if ((this.DataGrid != null) && this.Edge().HasValue)
            {
                this.ViewRow.AutoSize();
                e.Handled = true;
            }
        }

        private void SetCustomDefaultValues()
        {
            base.IsTabStop = false;
            base.SetBinding(BorderThicknessNewProperty, new Binding().From<DataGridCellPresenter>(this, x => x.BorderThickness));
            TapHelper helper = new TapHelper(this, false);
            helper.DoubleTapped += new EventHandler<TappedEventArgs>(this.ResizeMouseDoubleTapped);
        }

        protected internal virtual void Unload()
        {
            this.GoToReadOnlyState();
            this.ForceMouseOver = false;
            this.IsEditing = false;
        }

        public void UpdateCurrentCell()
        {
            DataGridCell currentCell = this.View.Model.FocusAndEditingManager.CurrentCell;
            bool flag = (((currentCell != null) && this.View.Viewport.Range(currentCell).Contains(this.Cell)) && this.View.Viewport.IsMaster(this.Cell)) && this.DataGrid.Focused;
            if (this.IsCurrent != flag)
            {
                this.IsCurrent = flag;
            }
        }

        private void UpdateCursor()
        {
            if (VisualTreeHelper.GetChildrenCount(this) > 0)
            {
                FrameworkElement child = (FrameworkElement)VisualTreeHelper.GetChild(this, 0);
                child.Cursor = this.Edge().HasValue ? Cursors.SizeNS : null;
            }
        }

        public FrameworkElement UpdateEditingCell()
        {
            DataGridCell currentCell = this.View.Model.FocusAndEditingManager.CurrentCell;
            bool flag = ((currentCell != null) && (currentCell == this.Cell)) && currentCell.IsEditing;
            if (this.IsEditing != flag)
            {
                this.IsEditing = flag;
                if (this.IsEditing)
                {
                    return this.GoToEditingState();
                }
                this.GoToReadOnlyState();
            }
            else if (this.IsEditing)
            {
                return this.CellContent;
            }
            return null;
        }

        public void UpdateLines()
        {
            Thickness borderThickness = base.BorderThickness;
            Brush borderBrush = base.BorderBrush;
            if (this.DataGrid != null)
            {
                if (this._elementLeftLine != null)
                {
                    if (borderThickness.Left > 0.0)
                    {
                        this._elementLeftLine.Width = borderThickness.Left;
                        this._elementLeftLine.Visibility = Visibility.Visible;
                        this._elementLeftLine.Fill = borderBrush ?? (this.LeftLineBrush ?? this.DataGrid.VerticalGridLinesBrush);
                        Canvas.SetZIndex(this._elementLeftLine, (((borderBrush == null) && (this.LeftLineBrush == null)) ? -1 : 1) * 2);
                    }
                    else
                    {
                        this._elementLeftLine.Visibility = Visibility.Collapsed;
                    }
                }
                if (this._elementTopLine != null)
                {
                    if (borderThickness.Top > 0.0)
                    {
                        this._elementTopLine.Height = borderThickness.Top;
                        this._elementTopLine.Visibility = Visibility.Visible;
                        this._elementTopLine.Fill = borderBrush ?? (this.TopLineBrush ?? this.DataGrid.HorizontalGridLinesBrush);
                        Canvas.SetZIndex(this._elementTopLine, ((borderBrush == null) && (this.TopLineBrush == null)) ? -1 : 1);
                    }
                    else
                    {
                        this._elementTopLine.Visibility = Visibility.Collapsed;
                    }
                }
                if (this._elementRightLine != null)
                {
                    double num = Math.Max(borderThickness.Right, ((this.DataGrid.GridLinesVisibility & DataGridGridLinesVisibility.Vertical) == DataGridGridLinesVisibility.Vertical) ? ((double)1) : ((double)0));
                    if (num > 0.0)
                    {
                        this._elementRightLine.Width = num;
                        this._elementRightLine.Visibility = Visibility.Visible;
                        this._elementRightLine.Fill = borderBrush ?? (this.RightLineBrush ?? this.DataGrid.VerticalGridLinesBrush);
                        Canvas.SetZIndex(this._elementRightLine, (((borderBrush == null) && (this.RightLineBrush == null)) ? -1 : 1) * 2);
                    }
                    else
                    {
                        this._elementRightLine.Visibility = Visibility.Collapsed;
                    }
                }
                if (this._elementBottomLine != null)
                {
                    double num2 = Math.Max(borderThickness.Bottom, ((this.DataGrid.GridLinesVisibility & DataGridGridLinesVisibility.Horizontal) == DataGridGridLinesVisibility.Horizontal) ? ((double)1) : ((double)0));
                    if (num2 > 0.0)
                    {
                        this._elementBottomLine.Height = num2;
                        this._elementBottomLine.Visibility = Visibility.Visible;
                        this._elementBottomLine.Fill = borderBrush ?? (this.BottomLineBrush ?? this.DataGrid.HorizontalGridLinesBrush);
                        Canvas.SetZIndex(this._elementBottomLine, ((borderBrush == null) && (this.BottomLineBrush == null)) ? -1 : 1);
                        this._elementBottomLine.Opacity = (this.Row.ActualDetailsVisibility == Visibility.Collapsed) ? ((double)1) : ((double)0);
                    }
                    else
                    {
                        this._elementBottomLine.Visibility = Visibility.Collapsed;
                    }
                }
            }
        }

        public void UpdateMouseOver()
        {
            if (this.Cell != null)
            {
                this.ForceMouseOver = this.Cell.IsMouseOver;
            }
        }

        public void UpdateSelection()
        {
            bool isSelected = this.Cell.IsSelected;
            if (this._isSelected != isSelected)
            {
                this.IsSelected = isSelected;
            }
        }

        public void UpdateValidationState()
        {
            ValidationState valid = ValidationState.Valid;
            if (this.View.DataGrid.ShowValidationIndicators)
            {
                bool flag = false;
                foreach (DataGridRowError error in this.Row.Errors)
                {
                    if (error.ColumnNames.Contains(this.Column.Name))
                    {
                        flag = true;
                    }
                }
                valid = (flag && (this.Row == this.View.Model.FocusAndEditingManager.CurrentRow)) ? ValidationState.InvalidUnfocused : ValidationState.Valid;
            }
            this.ValidationState = valid;
        }

        // Properties
        public Brush BottomLineBrush
        {
            get
            {
                return (Brush)base.GetValue(BottomLineBrushProperty);
            }
            set
            {
                base.SetValue(BottomLineBrushProperty, value);
            }
        }

        bool IRecyclable.IsCollected
        {
            get
            {
                return this.IsCollected;
            }
        }

        public DataGridCell Cell
        {
            get
            {
                if (this.DataGrid == null)
                {
                    return null;
                }
                return this.DataGrid[this.Row, this.Column];
            }
        }

        public DataGridColumn Column
        {
            get
            {
                if (this.ViewColumn == null)
                {
                    return null;
                }
                return this.ViewColumn.Column;
            }
        }

        public CornerRadius CornerRadius
        {
            get
            {
                return (CornerRadius)base.GetValue(CornerRadiusProperty);
            }
            set
            {
                base.SetValue(CornerRadiusProperty, value);
            }
        }

        public DataGrid DataGrid
        {
            get
            {
                if (this.ViewRow == null)
                {
                    return null;
                }
                return this.ViewRow.DataGrid;
            }
        }

        public Style FocusStyle
        {
            get
            {
                return (Style)base.GetValue(FocusStyleProperty);
            }
            set
            {
                base.SetValue(FocusStyleProperty, value);
            }
        }

        internal bool ForceMouseOver
        {
            get
            {
                return (bool)base.GetValue(ForceMouseOverProperty);
            }
            set
            {
                base.SetValue(ForceMouseOverProperty, value);
            }
        }

        internal bool IsCollected { get; private set; }

        public bool IsCurrent
        {
            get
            {
                return (bool)base.GetValue(IsCurrentProperty);
            }
            set
            {
                base.SetValue(IsCurrentProperty, value);
            }
        }

        public bool IsEditing
        {
            get
            {
                return (bool)base.GetValue(IsEditingProperty);
            }
            set
            {
                base.SetValue(IsEditingProperty, value);
            }
        }

        internal bool IsLoading { get; set; }

        public bool IsMouseOver
        {
            get
            {
                return (bool)base.GetValue(IsMouseOverProperty);
            }
            internal set
            {
                base.SetValue(IsMouseOverProperty, value);
            }
        }

        public bool IsSelected
        {
            get
            {
                return (bool)base.GetValue(IsSelectedProperty);
            }
            set
            {
                base.SetValue(IsSelectedProperty, value);
            }
        }

        public Brush LeftLineBrush
        {
            get
            {
                return (Brush)base.GetValue(LeftLineBrushProperty);
            }
            set
            {
                base.SetValue(LeftLineBrushProperty, value);
            }
        }

        public DataGridCellsRange MergedRange
        {
            get
            {
                return (DataGridCellsRange)base.GetValue(MergedRangeProperty);
            }
            internal set
            {
                base.SetValue(MergedRangeProperty, value);
            }
        }

        internal Size MergedSize
        {
            get
            {
                int num;
                int num2;
                int num3;
                int num4;
                if ((!this.View.Viewport.VisibleRange(this.MergedRange, out num, out num2, out num3, out num4) || (this.View.Viewport.VisibleColumns.Items[num] != this.Column)) || (this.View.Viewport.VisibleRows.Items[num2] != this.Row))
                {
                    return new Size();
                }
                DataGridColumn column = this.View.Viewport.VisibleColumns.Items[num3];
                DataGridRow row = this.View.Viewport.VisibleRows.Items[num4];
                return new Size((column.ViewColumn.Offset - this.ViewColumn.Offset) + column.ViewColumn.RenderWidth, (row.ViewRow.Offset - this.ViewRow.Offset) + row.ViewRow.RenderHeight);
            }
        }

        public Brush MouseOverBrush
        {
            get
            {
                return (Brush)base.GetValue(MouseOverBrushProperty);
            }
            set
            {
                base.SetValue(MouseOverBrushProperty, value);
            }
        }

        public Brush PressedBrush
        {
            get
            {
                return (Brush)base.GetValue(PressedBrushProperty);
            }
            set
            {
                base.SetValue(PressedBrushProperty, value);
            }
        }

        public Brush RightLineBrush
        {
            get
            {
                return (Brush)base.GetValue(RightLineBrushProperty);
            }
            set
            {
                base.SetValue(RightLineBrushProperty, value);
            }
        }

        public DataGridRow Row
        {
            get
            {
                if (this.ViewRow == null)
                {
                    return null;
                }
                return this.ViewRow.Row;
            }
        }

        public Brush SelectedBackground
        {
            get
            {
                return (Brush)base.GetValue(SelectedBackgroundProperty);
            }
            set
            {
                base.SetValue(SelectedBackgroundProperty, value);
            }
        }

        public Brush TopLineBrush
        {
            get
            {
                return (Brush)base.GetValue(TopLineBrushProperty);
            }
            set
            {
                base.SetValue(TopLineBrushProperty, value);
            }
        }

        public Brush ValidationBackground
        {
            get
            {
                return (Brush)base.GetValue(ValidationBackgroundProperty);
            }
            set
            {
                base.SetValue(ValidationBackgroundProperty, value);
            }
        }

        public ValidationState ValidationState
        {
            get
            {
                return (ValidationState)base.GetValue(ValidationStateProperty);
            }
            set
            {
                base.SetValue(ValidationStateProperty, value);
            }
        }

        internal DataGridView View
        {
            get
            {
                if (this.ViewRow == null)
                {
                    return null;
                }
                return this.ViewRow.View;
            }
        }

        internal ViewColumn ViewColumn
        {
            get
            {
                return this._viewColumn;
            }
            set
            {
                if (this._viewColumn != value)
                {
                    this._viewColumn = value;
                    this.RaisePropertyChanged("Column");
                }
            }
        }

        internal ViewRow ViewRow
        {
            get
            {
                return this._viewRow;
            }
            set
            {
                if (this._viewRow != value)
                {
                    this._viewRow = value;
                    this.RaisePropertyChanged("Row");
                }
            }
        }
    }
}
